#include <stdio.h>
#include "c_string.h"
#include <string.h>

typedef unsigned char Bool;
#define True 1
#define False 0

static Bool CheckStringEQ(const char *actual, const char *expect, const char *func, int line)
{
    int result = strcmp(actual, expect);
    if (result == 0)
        return True;

    printf("Fail on %s, L%d\n  expect: %s\n  actual: %s\n", func, line, expect, actual);
    return False;
}

static Bool CheckIntEQ(int actual, int expect, const char* func, int line)
{
    if (actual == expect)
        return True;

    printf("Fail on %s, L%d\n  expect: %d\n  actual: %d\n", func, line, expect, actual);
    return False;
}

#define CHECK_STREQ(a, e)  CheckStringEQ((a), (e), __func__, __LINE__)
#define CHECK_INTEQ(a, e)  CheckIntEQ((a), (e), __func__, __LINE__)

Bool Test_Append()
{
    CString *s1 = CString_New("Hello ");
    CString_Append(s1, "World!");
    Bool res = CHECK_STREQ(CString_CStr(s1), "Hello World!");
    res &= CHECK_INTEQ(CString_Length(s1), 12);
    CString_Delete(s1);
    return res;
}

Bool Test_Concat()
{
    CString *s1 = CString_New("Welcome to my class!");
    CString *s2 = CString_New("Hope enjon.");

    CString *s3 = CString_Concat(s1, s2);
    Bool res = CHECK_STREQ(CString_CStr(s3), "Welcome to my class!Hope enjon.");

    CString_Delete(s1);
    CString_Delete(s2);
    CString_Delete(s3);

    return res;
}

Bool Test_Erase()
{
    CString *s1 = CString_New("ABC12345DEF");
    CString_Erase(s1, 3, 5);
    Bool res = CHECK_STREQ(CString_CStr(s1), "ABCDEF");
    CString_Delete(s1);
    return res;
}

int main() 
{
    int fail_num = 0;

    if (!Test_Append()) ++fail_num;
    if (!Test_Concat()) ++fail_num;
    if (!Test_Erase()) ++fail_num;

    if (fail_num == 0)
        puts("all success!");
    else
        printf("%d fail.\n", fail_num);

    return 0;
}
